﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Schema;
using System.Xml;
using System.IO;
using GingerBeard.IDL;
using GingerBeard.Utilities;
 
namespace IDLCompiler
{
	class Program
	{
		static TextWriter SelectWriter(CmdLineArgs cmdLineArgs)
		{
			if (cmdLineArgs["OUT"] == null)
				return System.Console.Out;
			else
			{
				return new StreamWriter(cmdLineArgs["OUT"]);
			}
		}
		static int Main(string[] args)
		{
			int exitCode = -1;

			String[] languageOptions = Enum.GetNames(typeof(Language));

			CmdLineArgs cmdLineArgs = new CmdLineArgs();
			cmdLineArgs.SupportedArgs.Add(new CmdLineArgs.SupportedArg("IN", "Input File", CmdLineArgs.SupportedArg.RequirementType.Required, new CmdLineArgs.InputFileHandler()));
			cmdLineArgs.SupportedArgs.Add(new CmdLineArgs.SupportedArg("LANGUAGE", "Output Language Type", CmdLineArgs.SupportedArg.RequirementType.Required, new CmdLineArgs.EnumHandler(languageOptions)));
			cmdLineArgs.SupportedArgs.Add(new CmdLineArgs.SupportedArg("GENSAVE", "Specify what saving code generation should be performed. Options are OFF (default), ON or OPTIMISED", CmdLineArgs.SupportedArg.RequirementType.Optional));
			cmdLineArgs.SupportedArgs.Add(new CmdLineArgs.SupportedArg("GENLOAD", "Specify what loading code generation should be performed. Options are OFF (default), ON or OPTIMISED", CmdLineArgs.SupportedArg.RequirementType.Optional));
			cmdLineArgs.SupportedArgs.Add(new CmdLineArgs.SupportedArg("ENDIAN", "Specify that endian swapping code should be generated", CmdLineArgs.SupportedArg.RequirementType.Optional));
			cmdLineArgs.SupportedArgs.Add(new CmdLineArgs.SupportedArg("OUT", "Specify the output file that generated could should be written to. If not supplied, code is written to standard out", CmdLineArgs.SupportedArg.RequirementType.Optional));

			try
			{				
				cmdLineArgs.Initialise(args);
					
				if (cmdLineArgs["?"] != null || cmdLineArgs["HELP"] != null)
				{
					throw new CmdLineArgs.MissingRequiredArgException("Help requested");
				}
				else
				{
					IDL idl = IDL.Create(cmdLineArgs["IN"]);

					CompileSettings settings = new CompileSettings();

					using (settings.OutputWriter = SelectWriter(cmdLineArgs))
					{
						String savingCodeOption = cmdLineArgs["GENSAVE"];
						String loadingCodeOption = cmdLineArgs["GENLOAD"];
						String endianOption = cmdLineArgs["ENDIAN"];

						settings.CodeGenSaving = savingCodeOption == null ? CodeGeneration.Off : CodeGeneration.On;
						settings.CodeGenLoading = loadingCodeOption == null ? CodeGeneration.Off : CodeGeneration.On;
						settings.Language = (Language)Enum.Parse(typeof(Language), cmdLineArgs["LANGUAGE"], true);
						settings.ShouldGenerateEndianSwappingCode = endianOption != null;

						Compiler.Compile(idl, settings);
					}

					exitCode = 0;
				}
			}
			catch (CmdLineArgs.MissingRequiredArgException e)
			{
				System.Console.WriteLine(e.Message);
				cmdLineArgs.PrintUsage();
				
			}
			catch (Exception e)
			{
				System.Console.WriteLine(e.Message);
			}

			return exitCode;
		}
	}
}
